package co.edu.unal.research.contentprovider.serializer;

import co.edu.unal.research.contentprovider.contentProviderDsl.AdditionalFeature;
import co.edu.unal.research.contentprovider.contentProviderDsl.BlobDataType;
import co.edu.unal.research.contentprovider.contentProviderDsl.ColumnType;
import co.edu.unal.research.contentprovider.contentProviderDsl.Configuration;
import co.edu.unal.research.contentprovider.contentProviderDsl.ContentProvider;
import co.edu.unal.research.contentprovider.contentProviderDsl.ContentProviderDslPackage;
import co.edu.unal.research.contentprovider.contentProviderDsl.IntegerDataType;
import co.edu.unal.research.contentprovider.contentProviderDsl.RealDataType;
import co.edu.unal.research.contentprovider.contentProviderDsl.Table;
import co.edu.unal.research.contentprovider.contentProviderDsl.TableColumn;
import co.edu.unal.research.contentprovider.contentProviderDsl.TableWrap;
import co.edu.unal.research.contentprovider.contentProviderDsl.TextDataType;
import co.edu.unal.research.contentprovider.services.ContentProviderDslGrammarAccess;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.serializer.acceptor.ISemanticSequenceAcceptor;
import org.eclipse.xtext.serializer.acceptor.SequenceFeeder;
import org.eclipse.xtext.serializer.diagnostic.ISemanticSequencerDiagnosticProvider;
import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic.Acceptor;
import org.eclipse.xtext.serializer.sequencer.AbstractSemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.GenericSequencer;
import org.eclipse.xtext.serializer.sequencer.ISemanticNodeProvider.INodesForEObjectProvider;
import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService;
import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient;

@SuppressWarnings("restriction")
public class AbstractContentProviderDslSemanticSequencer extends AbstractSemanticSequencer {

	@Inject
	protected ContentProviderDslGrammarAccess grammarAccess;
	
	@Inject
	protected ISemanticSequencerDiagnosticProvider diagnosticProvider;
	
	@Inject
	protected ITransientValueService transientValues;
	
	@Inject
	@GenericSequencer
	protected Provider<ISemanticSequencer> genericSequencerProvider;
	
	protected ISemanticSequencer genericSequencer;
	
	
	@Override
	public void init(ISemanticSequencer sequencer, ISemanticSequenceAcceptor sequenceAcceptor, Acceptor errorAcceptor) {
		super.init(sequencer, sequenceAcceptor, errorAcceptor);
		this.genericSequencer = genericSequencerProvider.get();
		this.genericSequencer.init(sequencer, sequenceAcceptor, errorAcceptor);
	}
	
	public void createSequence(EObject context, EObject semanticObject) {
		if(semanticObject.eClass().getEPackage() == ContentProviderDslPackage.eINSTANCE) switch(semanticObject.eClass().getClassifierID()) {
			case ContentProviderDslPackage.ADDITIONAL_FEATURE:
				if(context == grammarAccess.getAdditionalFeatureRule()) {
					sequence_AdditionalFeature(context, (AdditionalFeature) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.BLOB_DATA_TYPE:
				if(context == grammarAccess.getBlobDataTypeRule() ||
				   context == grammarAccess.getDataTypeRule()) {
					sequence_DataType(context, (BlobDataType) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.COLUMN_TYPE:
				if(context == grammarAccess.getColumnTypeRule()) {
					sequence_ColumnType(context, (ColumnType) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.CONFIGURATION:
				if(context == grammarAccess.getConfigurationRule()) {
					sequence_Configuration(context, (Configuration) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.CONTENT_PROVIDER:
				if(context == grammarAccess.getContentProviderRule()) {
					sequence_ContentProvider(context, (ContentProvider) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.INTEGER_DATA_TYPE:
				if(context == grammarAccess.getDataTypeRule() ||
				   context == grammarAccess.getIntegerDataTypeRule()) {
					sequence_DataType(context, (IntegerDataType) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.REAL_DATA_TYPE:
				if(context == grammarAccess.getDataTypeRule() ||
				   context == grammarAccess.getRealDataTypeRule()) {
					sequence_DataType(context, (RealDataType) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.TABLE:
				if(context == grammarAccess.getDataTypeRule() ||
				   context == grammarAccess.getTableRule()) {
					sequence_Table(context, (Table) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.TABLE_COLUMN:
				if(context == grammarAccess.getTableColumnRule()) {
					sequence_TableColumn(context, (TableColumn) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.TABLE_WRAP:
				if(context == grammarAccess.getColumnTypeRule() ||
				   context == grammarAccess.getTableWrapRule()) {
					sequence_TableWrap(context, (TableWrap) semanticObject); 
					return; 
				}
				else break;
			case ContentProviderDslPackage.TEXT_DATA_TYPE:
				if(context == grammarAccess.getDataTypeRule() ||
				   context == grammarAccess.getTextDataTypeRule()) {
					sequence_DataType(context, (TextDataType) semanticObject); 
					return; 
				}
				else break;
			}
		if (errorAcceptor != null) errorAcceptor.accept(diagnosticProvider.createInvalidContextOrTypeDiagnostic(semanticObject, context));
	}
	
	/**
	 * Constraint:
	 *     name=STRING
	 */
	protected void sequence_AdditionalFeature(EObject context, AdditionalFeature semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ContentProviderDslPackage.Literals.ADDITIONAL_FEATURE__NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ContentProviderDslPackage.Literals.ADDITIONAL_FEATURE__NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getAdditionalFeatureAccess().getNameSTRINGTerminalRuleCall_0(), semanticObject.getName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     type=DataType
	 */
	protected void sequence_ColumnType(EObject context, ColumnType semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ContentProviderDslPackage.Literals.COLUMN_TYPE__TYPE) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ContentProviderDslPackage.Literals.COLUMN_TYPE__TYPE));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getColumnTypeAccess().getTypeDataTypeParserRuleCall_0_0(), semanticObject.getType());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (authority=STRING basePath=STRING packageName=STRING)
	 */
	protected void sequence_Configuration(EObject context, Configuration semanticObject) {
		if(errorAcceptor != null) {
			if(transientValues.isValueTransient(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__AUTHORITY) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__AUTHORITY));
			if(transientValues.isValueTransient(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__BASE_PATH) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__BASE_PATH));
			if(transientValues.isValueTransient(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__PACKAGE_NAME) == ValueTransient.YES)
				errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, ContentProviderDslPackage.Literals.CONFIGURATION__PACKAGE_NAME));
		}
		INodesForEObjectProvider nodes = createNodeProvider(semanticObject);
		SequenceFeeder feeder = createSequencerFeeder(semanticObject, nodes);
		feeder.accept(grammarAccess.getConfigurationAccess().getAuthoritySTRINGTerminalRuleCall_3_0(), semanticObject.getAuthority());
		feeder.accept(grammarAccess.getConfigurationAccess().getBasePathSTRINGTerminalRuleCall_5_0(), semanticObject.getBasePath());
		feeder.accept(grammarAccess.getConfigurationAccess().getPackageNameSTRINGTerminalRuleCall_7_0(), semanticObject.getPackageName());
		feeder.finish();
	}
	
	
	/**
	 * Constraint:
	 *     (config+=Configuration tables+=Table+)
	 */
	protected void sequence_ContentProvider(EObject context, ContentProvider semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     {BlobDataType}
	 */
	protected void sequence_DataType(EObject context, BlobDataType semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     {IntegerDataType}
	 */
	protected void sequence_DataType(EObject context, IntegerDataType semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     {RealDataType}
	 */
	protected void sequence_DataType(EObject context, RealDataType semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     {TextDataType}
	 */
	protected void sequence_DataType(EObject context, TextDataType semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID type=ColumnType additionalFeatures+=AdditionalFeature*)
	 */
	protected void sequence_TableColumn(EObject context, TableColumn semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     table=[Table|ID]
	 */
	protected void sequence_TableWrap(EObject context, TableWrap semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
	
	
	/**
	 * Constraint:
	 *     (name=ID columns+=TableColumn+ primaryKey=STRING?)
	 */
	protected void sequence_Table(EObject context, Table semanticObject) {
		genericSequencer.createSequence(context, semanticObject);
	}
}
